#include "ObjectDatabase.h"
#include "Game.h"
#include "Util.h"
#include "StringLib.h"
#include <stdarg.h>

ObjectDatabase::ObjectDatabase() {
	// RANDOMIZED POTION/SCROLL NAMES
	PotionType potionTypeArray[NUM_POTION_TYPES];
	ScrollType scrollTypeArray[NUM_SCROLL_TYPES];
	for(int i = 0; i < NUM_POTION_TYPES; i++)
		potionTypeArray[i] = PotionType(i);
	for(int i = 0; i < NUM_SCROLL_TYPES; i++)
		scrollTypeArray[i] = ScrollType(i);
	for(int i = 0; i < 100; i++) {
		int randPotion1 = rand(NUM_POTION_TYPES);
		int randPotion2 = rand(NUM_POTION_TYPES);
		int randScroll1 = rand(NUM_SCROLL_TYPES);
		int randScroll2 = rand(NUM_SCROLL_TYPES);
		PotionType tempPotion = potionTypeArray[randPotion1];
		ScrollType tempScroll = scrollTypeArray[randScroll1];
		potionTypeArray[randPotion1] = potionTypeArray[randPotion2];
		potionTypeArray[randPotion2] = tempPotion;
		scrollTypeArray[randScroll1] = scrollTypeArray[randScroll2];
		scrollTypeArray[randScroll2] = tempScroll;
	}
	for(int i = 0; i < NUM_POTION_TYPES; i++)
		m_potionNames[i] = potionTypeArray[i];
	for(int i = 0; i < NUM_SCROLL_TYPES; i++)
		m_scrollNames[i] = scrollTypeArray[i];

	// NPC
	// type, dlevel, commonality, humanoid, gender, level, levelRange, str, com, nim, lor, per, health, satiation, weight, poisoned, name, description
	initNpcInfo(NT_ABOMINABLE_HORROR, 1, 500, false, 0, 1, 3, 5, 2, 4, 5, 5, 30, 1, 5, false, "servant of glaaki", "Servant of Glaaki");
	initNpcInfo(NT_ABOMINATION, 3, 300, false, 0, 3, 5, 9, 4, 9, 3, 4, 50, 1, 5, false, "abomination", "Abomination");
	initNpcInfo(NT_DEATH_FIEND, 3, 300, false, 0, 3, 2, 4, 8, 2, 9, 1, 60, 1, 5, false, "death fiend", "Death Fiend");
	initNpcInfo(NT_HORRIFYING_MASS, 6, 300, false, 0, 6, 2, 9, 8, 3, 9, 6, 100, 1, 5, false, "horrifying mass", "Horrifying Mass");
	initNpcInfo(NT_MUTANT, 8, 300, false, 0, 8, 5, 8, 4, 8, 9, 10, 100, 1, 5, false, "yithian", "Yithian");
	initNpcInfo(NT_SLIME, 13, 300, false, 0, 13, 3, 12, 10, 15, 10, 5, 100, 1, 5, false, "tentacled monstrosity", "Tentacled Monstrosity");
	initNpcInfo(NT_SOUL_EATER, 4, 300, false, 0, 4, 9, 5, 1, 7, 10, 10, 70, 1, 5, false, "shoggoth", "Shoggoth");
	initNpcInfo(NT_TENTACLED_STARSPAWN, 7, 300, false, 0, 1, 10, 10, 5, 5, 5, 5, 20, 1, 5, false, "formless spawn", "Formless Spawn");
	initNpcInfo(NT_THRASHING_HORROR, 20, 100, false, 0, 20, 1, 20, 10, 20, 10, 15, 200, 1, 5, false, "cthonian", "Cthonian");

	// PLAYER
	// type, str, com, nim, lor, per, health
	initPlayerInfo(PT_DEFAULT_PLAYER, 10, 10, 10, 10, 10, 100, "This is you, an ordinary human.");

	// AMMO
	// type, dlevel, commonality, weight, name, plural, description
	initAmmoInfo(AT_9MM, 1, 10000, 0, "9mm bullet", "9mm bullets", "Projectile for a gun that fires 9mm rounds.");

	// ARMOR
	// type, dlevel, commonality, family, armor, dodge, weight, name, description
	initArmorInfo(AT_HEAD_ARMET, 1, 500, AF_HEAD, 1, 0, 10, "armet", "A helmet that completely encloses the head.");
	initArmorInfo(AT_BODY_LEATHER_SCALE, 1, 500, AF_BODY, 3, 3, 30, "leather scale armor", "A leather base lined with hard scales for extra support.");
	initArmorInfo(AT_BODY_CHAIN, 5, 300, AF_BODY, 6, 1, 50, "chain mail", "Small links of metal chained together, to provide maximum protection without sacrificing mobility.");
	initArmorInfo(AT_HANDS_GAUNTLETS, 1, 500, AF_HANDS, 1, 0, 10, "gauntlets", "Long gloves that protect not only the hands, but the forearm as well.");
	initArmorInfo(AT_LEGS_LEGGINGS, 1, 500, AF_LEGS, 2, 0, 15, "leggings", "A pair of cuisses and greaves, which fully protect a wearer's legs.");
	initArmorInfo(AT_FEET_SABATONS, 1, 500, AF_FEET, 2, 0, 10, "sabatons", "A pair of metal shoes, worn by knights.");

	// FOOD
	// type, dlevel, commonality, satiation, weight, name, plural, description
	initFoodInfo(FT_BREAD_RATION, 5, 500, 700, 2, "bread ration", "bread rations", "A loaf of bread. It's a little stale.");
	initFoodInfo(FT_MEAT_RATION, 10, 500, 1000, 3, "meat ration", "meat rations", "A slab of preserved meat. You hope it came from a cow.");

	// INGREDIENT
	// type, dlevel, commonality, family, weight, name, plural, dsecription
	initIngredientInfo(IT_HERB_PAPRIKA, 1, 200, IF_HERB, 1, "smidgen of paprika", "smidgens of paprika", "A spicy seasoning.");
	initIngredientInfo(IT_HERB_PARSLEY, 3, 200, IF_HERB, 1, "sprig of parsley", "sprigs of parsley", "An herb often used for garnishment.");
	initIngredientInfo(IT_HERB_MUSHROOM, 6, 100, IF_HERB, 1, "mushroom", "mushrooms", "Mushrooms are often found in the dark, damp corners of dungeons.");
	initIngredientInfo(IT_ALCH_NEWT_EYE, 3, 100, IF_ALCH, 1, "newt eye", "newt eyes", "The eye of a newt. You sense it gazing back at you.");
	initIngredientInfo(IT_ALCH_RAT_TAIL, 5, 100, IF_ALCH, 1, "rat tail", "rat tails", "The severed tail of a rat. The rat is nowhere to be found.");
	initIngredientInfo(IT_ALCH_GUNPOWDER, 15, 75, IF_ALCH, 1, "pile of gunpowder", "piles of gunpowder", "An explosive powder.");
	initIngredientInfo(IT_METAL_SCRAP, 1, 50, IF_METAL, 1, "piece of scrap metal", "pieces of scrap metal", "A versatile piece of scrap metal, which can be used to make a number of different items.");

	// MISC
	// type, dlevel, commonality, weight, identified, name, plural, description
	initMiscInfo(MT_KEY_SQUARE, 5, 100, 1, true, "square key", "square keys", "A special key that will open square locks.");
	initMiscInfo(MT_KEY_ROUND, 5, 100, 1, true, "round key", "round keys", "A special key that will open round locks.");
	initMiscInfo(MT_KEY_SKELETON, 20, 50, 1, true, "skeleton key", "skeleton keys", "A mysterious key that seems to be able to open any lock.");
	initMiscInfo(MT_VICTORY_ITEM, 0, 0, 1, true, "victory item", "victory items", "If you're holding this, quickly get to the top floor and escape the dungeon!");

	// POTION
	// type, dlevel, commonality, weight, name, plural, description
	initPotionInfo(PT_HEALING, 5, 500, 2, "healing potion", "healing potions", "A potion with regenerative capabilities. It can also cure certain status ailments.", "orange potion", "an unidentified orange potion", "orange potions");
	initPotionInfo(PT_POISON, 5, 200, 2, "poison potion", "poison potions", "A poisonous liquid sits in this vial.", "green potion", "an unidentified  green potion", "green potions");
	initPotionInfo(PT_INVIS, 15, 100, 2, "invisibility potion", "invisibility potions", "Drinking this will cause you to temporarily turn invisible!", "black potion", "an unidentified black potion", "black potions");
	initPotionInfo(PT_GAIN_ATTR, 20, 50, 2, "potion of gain attribute", "potions of gain attribute", "An extremely rare and valuable potion.", "clear potion", "an unidentified clear potion", "clear potions");
	initPotionInfo(PT_WATER, 1, 50, 2, "vial of water", "It's ordinary water.", "vials of water", "blue potion", "an unidentified blue potion", "blue potions");

	initShieldInfo(ST_BUCKLER, 1, 500, 5, 10, "buckler", "A small, round shield.");
	initShieldInfo(ST_KITE, 5, 300, 15, 25, "kite shield", "A large shield, shaped like a kite.");

	// TOOL
	// type, dlevel, commonality, weight, name, description
	initToolInfo(TT_PLANT, 5, 400, 10, "gardening tools", "A set of gardening tools.");
	initToolInfo(TT_METAL, 5, 400, 10, "metal tools", "A set of tools for dismantling metal heaps and electronics.");

	// MELEE WEAPON
	// type, dlevel, commonality, family, dice, sides, bonus, accuracy, speed, weight, grip, name, description
	initMeleeWeaponInfo(MWT_SHORT_SWORD, 1, 200, WF_SWORD, 1, 4, 0, 8, 90, 10, GT_ONE, "short sword", "Smaller than your average sword.");
	initMeleeWeaponInfo(MWT_LONG_SWORD, 5, 200, WF_SWORD, 2, 5, 0, 4, 110, 18, GT_ONE, "long sword", "A sword with a long blade.");
	initMeleeWeaponInfo(MWT_BASTARD_SWORD, 10, 200, WF_SWORD, 3, 5, 0, 0, 140, 25, GT_ONE_FIVE, "bastard sword", "A large sword that can be held with either one or two hands.");
	initMeleeWeaponInfo(MWT_TWO_HANDED_SWORD, 20, 200, WF_SWORD, 3, 8, 0, -2, 170, 40, GT_TWO, "two handed sword", "An enormous sword that requires enormous strength to swing.");
	initMeleeWeaponInfo(MWT_CURVED_SWORD, 15, 100, WF_SWORD, 4, 4, 0, 1, 130, 20, GT_ONE, "curved sword", "An exotic blade from distant lands.");
	initMeleeWeaponInfo(MWT_MACE, 1, 200, WF_MACE, 2, 2, 0, 4, 100, 14, GT_ONE, "mace", "A stick with a large ball on the end.");
	initMeleeWeaponInfo(MWT_FLAIL, 10, 200, WF_MACE, 3, 3, 0, 0, 120, 18, GT_ONE, "flail", "The old ball and chain.");
	initMeleeWeaponInfo(MWT_MORNINGSTAR, 15, 100, WF_MACE, 4, 4, 0, 0, 110, 15, GT_ONE, "morningstar", "It's a mace, but with spikes!");
	initMeleeWeaponInfo(MWT_SHORT_SPEAR, 1, 200, WF_SPEAR, 3, 1, 0, 3, 110, 12, GT_ONE, "short spear", "A small spear that excels at precision strikes.");
	initMeleeWeaponInfo(MWT_LONG_SPEAR, 5, 200, WF_SPEAR, 5, 2, 0, 0, 130, 18, GT_ONE_FIVE, "long spear", "A long spear, useful for keeping enemies at range.");
	initMeleeWeaponInfo(MWT_HALBERD, 13, 200, WF_SPEAR, 8, 2, 0, -2, 160, 30, GT_TWO, "halberd", "A dangerous combination of spear and axe.");
	initMeleeWeaponInfo(MWT_LANCE, 20, 100, WF_SPEAR, 8, 4, 0, -5, 200, 50, GT_TWO, "lance", "Guaranteed to impale anything it hits - if it hits.");
	initMeleeWeaponInfo(MWT_AXE, 1, 200, WF_AXE, 1, 2, 2, 4, 100, 12, GT_ONE, "axe", "A small axe, slightly larger than a hatchet.");
	initMeleeWeaponInfo(MWT_WAR_AXE, 7, 150, WF_AXE, 2, 3, 3, 0, 120, 20, GT_ONE, "war axe", "An axe made for war. The weapon of choice of scalpers.");
	initMeleeWeaponInfo(MWT_GREAT_AXE, 14, 200, WF_AXE, 3, 3, 5, -2, 150, 40, GT_TWO, "great axe", "A massive axe that's hard to hold and even harder to swing.");
	initMeleeWeaponInfo(MWT_EXECUTIONERS_AXE, 20, 150, WF_AXE, 4, 4, 8, -5, 200, 60, GT_TWO, "executioner's axe", "Heads will roll.");

	// RANGED WEAPON
	// type, dlevel, commonality, family, dice, sides, bonus, accuracy, speed, weight, range, maxAmmo, grip, ammo, name, description
	initRangedWeaponInfo(RWT_PISTOL, 1, 20000, WF_HANDGUN, 6, 4, 0, 5, 100, 10, 8, 8, GT_ONE_FIVE, AT_9MM, "pistol", "A 9mm pistol.");
	
	// MATERIAL
	// type, dlevel, commanlity, name
	initMaterialInfo(MT_OAK, 1, 200, "oak");
	initMaterialInfo(MT_WALNUT, 2, 200, "walnut");
	initMaterialInfo(MT_COPPER, 3, 500, "copper");
	initMaterialInfo(MT_BRONZE, 5, 300, "bronze");
	initMaterialInfo(MT_BRASS, 8, 300, "brass");
	initMaterialInfo(MT_IRON, 15, 500, "iron");

	// SCROLL
	// type, dlevel, commonality, weight, name, plural, description
	initScrollInfo(ST_IDENTIFY, 1, 500, 1, "scroll of identify", "scrolls of identify", "This spell will identify an item's attributes and status.", "scroll of ESRFSEH", "an unidentified scroll", "scrolls of ESRFSEH");
	initScrollInfo(ST_UNCURSE, 1, 500, 1, "scroll of uncurse", "scrolls of uncurse", "This spell will remove a curse on any item.", "scroll of AAAAAA", "an unidentified scroll", "scrolls of AAAAAA");

	// ITEMCONTAINER
	// type, dlevel, commonality, minitems, maxitems, lockable, breakable, name, description
	initItemContainerInfo(ICT_BOX, 5, 200, 0, 2, true, false, "box", "A box. Maybe there's something inside.");
	initItemContainerInfo(ICT_CHEST, 15, 100, 1, 6, true, false, "treasure chest", "There's bound to be something good in here.");
	initItemContainerInfo(ICT_POTTERY, 1, 400, 0, 1, false, true, "pot", "A fine piece of pottery... you think you hear something moving inside.");

	// RESOURCE
	// type, dlevel, commonality, family, health, quality, ingredient, bonus, name, description
	initResourceInfo(RT_PT_PAPRIKA, 1, 200, RF_PLANT, 10, TP_NOVICE, IT_HERB_PAPRIKA, IT_ALCH_NEWT_EYE, "paprika plant", "A plant growing the necessary fruit for paprika.");
	initResourceInfo(RT_PT_PARSLEY, 3, 200, RF_PLANT, 20, TP_NONE, IT_HERB_PARSLEY, IT_ALCH_RAT_TAIL, "parsley plant", "This plant seems to be growing parsley.");
	initResourceInfo(RT_PT_MUSHROOM, 6, 150, RF_PLANT, 30, TP_ADEPT, IT_HERB_MUSHROOM, 0, "mushrooms", "A small cluster of mushrooms.");
	initResourceInfo(RT_MT_SCRAP, 1, 200, RF_METAL, 10, TP_NOVICE, IT_METAL_SCRAP, IT_ALCH_GUNPOWDER, "pile of scrap metal", "A pile of scrap metal from a variety of unknown sources.");

	// TRAP
	// type, dlevel, commonality, name, description
	initTrapInfo(TT_DAGGER, 5, 300, "dagger trap", "A trap spring-loaded with daggers.");

	// TALENT
	// talent, str, com, nim, lor, per, gender, name, description, numPrereqs, prereqs...
	initTalentInfo(TAL_STR_1, 0, 0, 0, 0, 0, 4, "Strength 1", "This increases your strength by one.", 0);
	initTalentInfo(TAL_STR_2, 0, 0, 0, 0, 0, 4, "Strength 2", "This increases your strength by one.", 1, TAL_STR_1);
	initTalentInfo(TAL_STR_3, 0, 0, 0, 0, 0, 4, "Strength 3", "This increases your strength by one.", 1, TAL_STR_2);
	initTalentInfo(TAL_COM_1, 0, 0, 0, 0, 0, 4, "Composure 1", "This increases your composure by one.", 0);
	initTalentInfo(TAL_COM_2, 0, 0, 0, 0, 0, 4, "Composure 2", "This increases your composure by one.", 1, TAL_COM_1);
	initTalentInfo(TAL_COM_3, 0, 0, 0, 0, 0, 4, "Composure 3", "This increases your composure by one.", 1, TAL_COM_2);
	initTalentInfo(TAL_NIM_1, 0, 0, 0, 0, 0, 4, "Nimbleness 1", "This increases your nimbelness by one.", 0);
	initTalentInfo(TAL_NIM_2, 0, 0, 0, 0, 0, 4, "Nimbleness 2", "This increases your nimbelness by one.", 1, TAL_NIM_1);
	initTalentInfo(TAL_NIM_3, 0, 0, 0, 0, 0, 4, "Nimbleness 3", "This increases your nimbelness by one.", 1, TAL_NIM_2);
	initTalentInfo(TAL_LOR_1, 0, 0, 0, 0, 0, 4, "Lore 1", "This increases your lore by one.", 0);
	initTalentInfo(TAL_LOR_2, 0, 0, 0, 0, 0, 4, "Lore 2", "This increases your lore by one.", 1, TAL_LOR_1);
	initTalentInfo(TAL_LOR_3, 0, 0, 0, 0, 0, 4, "Lore 3", "This increases your lore by one.", 1, TAL_LOR_2);
	initTalentInfo(TAL_PER_1, 0, 0, 0, 0, 0, 4, "Perception 1", "This increases your perception by one.", 0);
	initTalentInfo(TAL_PER_2, 0, 0, 0, 0, 0, 4, "Perception 2", "This increases your perception by one.", 1, TAL_PER_1);
	initTalentInfo(TAL_PER_3, 0, 0, 0, 0, 0, 4, "Perception 3", "This increases your perception by one.", 1, TAL_PER_2);
	initTalentInfo(TAL_SATIATION_1, 10, 0, 0, 0, 0, GT_MALE, "Satiation 1", "Your metabolism slows down.", 0);
	initTalentInfo(TAL_SATIATION_2, 12, 0, 0, 0, 0, GT_MALE, "Satiation 2", "Your metabolism really slows down.", 1, TAL_SATIATION_1);
}

ObjectDatabase::~ObjectDatabase() {
}

void ObjectDatabase::save(std::ofstream& file) const {
	for(int i = 0; i < NUM_POTION_TYPES; i++)
		file << m_potionNames[i] << "\n";
	for(int i = 0; i < NUM_SCROLL_TYPES; i++)
		file << m_scrollNames[i] << "\n";
}

void ObjectDatabase::load(std::ifstream& file) {
	std::string line;
	for(int i = 0; i < NUM_POTION_TYPES; i++) {
		std::getline(file, line);
		m_potionNames[i] = PotionType(Util::strToInt(line));
	}
	for(int i = 0; i < NUM_SCROLL_TYPES; i++) {
		std::getline(file, line);
		m_scrollNames[i] = ScrollType(Util::strToInt(line));
	}
}

void ObjectDatabase::initNpcInfo(NpcType type, int dlevel, int commonality, bool humanoid, int gender, int level, int levelRange, int str, int com, int nim, int lor, int per,
		int health, int satiation, int weight, bool poisoned, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_NPC_TYPE, type, name);
	g_stringLib->setObjectString(TH_NPC_TYPE, type, description);
	m_npc[type].dlevel = dlevel;
	m_npc[type].commonality = commonality;
	m_npc[type].humanoid = humanoid;
	m_npc[type].gender = gender;
	m_npc[type].level = level;
	m_npc[type].levelRange = levelRange;
	m_npc[type].stats[STR] = str;
	m_npc[type].stats[COM] = com;
	m_npc[type].stats[NIM] = nim;
	m_npc[type].stats[LOR] = lor;
	m_npc[type].stats[PER] = per;
	m_npc[type].health = health;
	m_npc[type].corpseSatiation = satiation;
	m_npc[type].corpseWeight = weight;
	m_npc[type].corpsePoisoned = poisoned;
}

void ObjectDatabase::initPlayerInfo(PlayerType type, int str, int com, int nim, int lor, int per, int health, std::string description) {
	g_stringLib->setObjectString(TH_PLAYER_TYPE, type, g_options.o_name);
	g_stringLib->setObjectString(TH_PLAYER_TYPE, type, description);
	m_player[type].stats[STR] = str;
	m_player[type].stats[COM] = com;
	m_player[type].stats[NIM] = nim;
	m_player[type].stats[LOR] = lor;
	m_player[type].stats[PER] = per;
	m_player[type].health = health;
}

void ObjectDatabase::initAmmoInfo(AmmoType type, int dlevel, int commonality, int weight, std::string name, std::string plural, std::string description) {
	g_stringLib->setObjectString(TH_AMMO_TYPE, type, name);
	g_stringLib->setObjectString(TH_AMMO_TYPE, type, description);
	g_stringLib->setObjectString(TH_AMMO_TYPE, type, plural);
	g_idDatabase[TH_AMMO_TYPE][type] = true;
	m_ammo[type].dlevel = dlevel;
	m_ammo[type].commonality = commonality;
	m_ammo[type].weight = weight;
}

void ObjectDatabase::initArmorInfo(ArmorType type, int dlevel, int commonality, ArmorFamily family, int armor, int dodge, int weight, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_ARMOR_TYPE, type, name);
	g_stringLib->setObjectString(TH_ARMOR_TYPE, type, description);
	g_idDatabase[TH_ARMOR_TYPE][type] = true;
	m_armor[type].dlevel = dlevel;
	m_armor[type].commonality = commonality;
	m_armor[type].family = family;
	m_armor[type].armor = armor;
	m_armor[type].dodge = dodge;
	m_armor[type].weight = weight;
}

void ObjectDatabase::initFoodInfo(FoodType type, int dlevel, int commonality, int satiation, int weight, std::string name, std::string plural, std::string description) {
	g_stringLib->setObjectString(TH_FOOD_TYPE, type, name);
	g_stringLib->setObjectString(TH_FOOD_TYPE, type, description);
	g_stringLib->setObjectString(TH_FOOD_TYPE, type, plural);
	g_idDatabase[TH_FOOD_TYPE][type] = true;
	m_food[type].dlevel = dlevel;
	m_food[type].commonality = commonality;
	m_food[type].satiation = satiation;
	m_food[type].weight = weight;
}

void ObjectDatabase::initIngredientInfo(IngredientType type, int dlevel, int commonality, IngredientFamily family, int weight, std::string name, std::string plural, std::string description) {
	g_stringLib->setObjectString(TH_INGREDIENT_TYPE, type, name);
	g_stringLib->setObjectString(TH_INGREDIENT_TYPE, type, description);
	g_stringLib->setObjectString(TH_INGREDIENT_TYPE, type, plural);
	g_idDatabase[TH_INGREDIENT_TYPE][type] = true;
	m_ingredient[type].dlevel = dlevel;
	m_ingredient[type].commonality = commonality;
	m_ingredient[type].family = family;
	m_ingredient[type].weight = weight;
}

void ObjectDatabase::initMiscInfo(MiscType type, int dlevel, int commonality, int weight, bool identified, std::string name, std::string plural, std::string description) {
	g_stringLib->setObjectString(TH_MISC_TYPE, type, name);
	g_stringLib->setObjectString(TH_MISC_TYPE, type, description);
	g_stringLib->setObjectString(TH_MISC_TYPE, type, plural);
	g_idDatabase[TH_MISC_TYPE][type] = identified;
	m_misc[type].dlevel = dlevel;
	m_misc[type].commonality = commonality;
	m_misc[type].weight = weight;
}

void ObjectDatabase::initPotionInfo(PotionType type, int dlevel, int commonality, int weight, std::string name, std::string plural, std::string description, std::string scrambledName, std::string scrambledDescription, std::string scrambledPlural) {
	g_stringLib->setObjectString(TH_POTION_TYPE, type, name);
	g_stringLib->setObjectString(TH_POTION_TYPE, type, description);
	g_stringLib->setObjectString(TH_POTION_TYPE, type, plural);
	g_stringLib->setObjectString(TH_POTION_TYPE, type, scrambledName);
	g_stringLib->setObjectString(TH_POTION_TYPE, type, scrambledDescription);
	g_stringLib->setObjectString(TH_POTION_TYPE, type, scrambledPlural);
	g_idDatabase[TH_POTION_TYPE][type] = false;
	m_potion[type].dlevel = dlevel;
	m_potion[type].commonality = commonality;
	m_potion[type].weight = weight;
}

void ObjectDatabase::initShieldInfo(ShieldType type, int dlevel, int commonality, int block, int weight, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_SHIELD_TYPE, type, name);
	g_stringLib->setObjectString(TH_SHIELD_TYPE, type, description);
	g_idDatabase[TH_SHIELD_TYPE][type] = true;
	m_shield[type].dlevel = dlevel;
	m_shield[type].commonality = commonality;
	m_shield[type].block = block;
	m_shield[type].weight = weight;
}

void ObjectDatabase::initToolInfo(ToolType type, int dlevel, int commonality, int weight, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_TOOL_TYPE, type, name);
	g_stringLib->setObjectString(TH_TOOL_TYPE, type, description);
	g_idDatabase[TH_TOOL_TYPE][type] = true;
	m_tool[type].dlevel = dlevel;
	m_tool[type].commonality = commonality;
	m_tool[type].weight = weight;
}

void ObjectDatabase::initMeleeWeaponInfo(MeleeWeaponType type, int dlevel, int commonality, WeaponFamily family, int numDie, int diceSides, int attackBonus, int accuracy, int speed, int weight,
		GripType grip, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_MELEE_WEAPON_TYPE, type, name);
	g_stringLib->setObjectString(TH_MELEE_WEAPON_TYPE, type, description);
	g_idDatabase[TH_MELEE_WEAPON_TYPE][type] = true;
	m_meleeWeapon[type].dlevel = dlevel;
	m_meleeWeapon[type].commonality = commonality;
	m_meleeWeapon[type].family = family;
	m_meleeWeapon[type].numDie = numDie;
	m_meleeWeapon[type].diceSides = diceSides;
	m_meleeWeapon[type].accuracy = accuracy;
	m_meleeWeapon[type].speed = speed;
	m_meleeWeapon[type].grip = grip;
	m_meleeWeapon[type].weight = weight;
	m_meleeWeapon[type].attackBonus = attackBonus;
}

void ObjectDatabase::initRangedWeaponInfo(RangedWeaponType type, int dlevel, int commonality, WeaponFamily family, int numDie, int diceSides, int attackBonus, int accuracy, int speed, int weight, int range,
		int maxAmmo, GripType grip, AmmoType ammo, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_RANGED_WEAPON_TYPE, type, name);
	g_stringLib->setObjectString(TH_RANGED_WEAPON_TYPE, type, description);
	g_idDatabase[TH_RANGED_WEAPON_TYPE][type] = true;
	m_rangedWeapon[type].dlevel = dlevel;
	m_rangedWeapon[type].commonality = commonality;
	m_rangedWeapon[type].family = family;
	m_rangedWeapon[type].numDie = numDie;
	m_rangedWeapon[type].diceSides = diceSides;
	m_rangedWeapon[type].accuracy = accuracy;
	m_rangedWeapon[type].speed = speed;
	m_rangedWeapon[type].grip = grip;
	m_rangedWeapon[type].weight = weight;
	m_rangedWeapon[type].attackBonus = attackBonus;
	m_rangedWeapon[type].range = range;
	m_rangedWeapon[type].ammo = ammo;
	m_rangedWeapon[type].maxAmmo = maxAmmo;
}

void ObjectDatabase::initMaterialInfo(MaterialType type, int dlevel, int commonality, std::string name) {
	g_stringLib->setMiscString(MST_MATERIAL, type, name);
	m_material[type].dlevel = dlevel;
	m_material[type].commonality = commonality;
}

void ObjectDatabase::initScrollInfo(ScrollType type, int dlevel, int commonality, int weight, std::string name, std::string plural, std::string description, std::string scrambledName, std::string scrambledDescription, std::string scrambledPlural) {
	g_stringLib->setObjectString(TH_SCROLL_TYPE, type, name);
	g_stringLib->setObjectString(TH_SCROLL_TYPE, type, description);
	g_stringLib->setObjectString(TH_SCROLL_TYPE, type, plural);
	g_stringLib->setObjectString(TH_SCROLL_TYPE, type, scrambledName);
	g_stringLib->setObjectString(TH_SCROLL_TYPE, type, scrambledDescription);
	g_stringLib->setObjectString(TH_SCROLL_TYPE, type, scrambledPlural);
	g_idDatabase[TH_SCROLL_TYPE][type] = false;
	m_scroll[type].dlevel = dlevel;
	m_scroll[type].commonality = commonality;
	m_scroll[type].weight = weight;
}

void ObjectDatabase::initItemContainerInfo(ItemContainerType type, int dlevel, int commonality, int minItems, int maxItems, bool lock, bool breakable, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_ITEMCONTAINER_TYPE, type, name);
	g_stringLib->setObjectString(TH_ITEMCONTAINER_TYPE, type, description);
	m_itemcontainer[type].dlevel = dlevel;
	m_itemcontainer[type].commonality = commonality;
	m_itemcontainer[type].minItems = minItems;
	m_itemcontainer[type].maxItems = maxItems;
	m_itemcontainer[type].lock = lock;
	m_itemcontainer[type].breakable = breakable;
}

void ObjectDatabase::initResourceInfo(ResourceType type, int dlevel, int commonality, ResourceFamily family, int health, int quality, IngredientType ingredient, int bonusflag, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_RESOURCE_TYPE, type, name);
	g_stringLib->setObjectString(TH_RESOURCE_TYPE, type, description);
	m_resource[type].dlevel = dlevel;
	m_resource[type].commonality = commonality;
	m_resource[type].family = family;
	m_resource[type].health = health;
	m_resource[type].quality = quality;
	m_resource[type].ingredient = ingredient;
	m_resource[type].bonusflag = bonusflag;
}

void ObjectDatabase::initTrapInfo(TrapType type, int dlevel, int commonality, std::string name, std::string description) {
	g_stringLib->setObjectString(TH_TRAP_TYPE, type, name);
	g_stringLib->setObjectString(TH_TRAP_TYPE, type, description);
	m_trap[type].dlevel = dlevel;
	m_trap[type].commonality = commonality;
}

void ObjectDatabase::initTalentInfo(Talent talent, int str, int com, int nim, int lor, int per, int gender, std::string name, std::string description, int numPrereqs, ...) {
	g_stringLib->setMiscString(MST_TALENT, talent, name);
	g_stringLib->setMiscString(MST_TALENT, talent, description);
	std::set<Talent> prereqTalents;
	va_list vars;
    va_start(vars, numPrereqs);
	for(int i = 0; i < numPrereqs; i++)
		prereqTalents.insert(Talent(va_arg(vars, int)));
	va_end(vars);
	m_talent[talent].stats[STR] = str;
	m_talent[talent].stats[COM] = com;
	m_talent[talent].stats[NIM] = nim;
	m_talent[talent].stats[LOR] = lor;
	m_talent[talent].stats[PER] = per;
	m_talent[talent].gender = gender;
	m_talent[talent].prereqs = prereqTalents;
}
